﻿Imports System.Runtime.InteropServices

Module ModMain

    <Flags()> _
    Private Enum ThreadAccess As Integer
        TERMINATE = &H1
        SUSPEND_RESUME = &H2
        GET_CONTEXT = &H8
        SET_CONTEXT = &H10
        SET_INFORMATION = &H20
        QUERY_INFORMATION = &H40
        SET_THREAD_TOKEN = &H80
        IMPERSONATE = &H100
        DIRECT_IMPERSONATION = &H200
    End Enum
    <DllImport("kernel32.dll")> _
    Private Function OpenThread(ByVal dwDesiredAccess As ThreadAccess, <MarshalAs(UnmanagedType.Bool)> ByVal bInheritHandle As Boolean, ByVal dwThreadId As Integer) As IntPtr
    End Function
    <DllImport("kernel32.dll")> _
    Function SuspendThread(hThread As IntPtr) As UInteger
    End Function
    <DllImport("kernel32.dll")> _
    Function ResumeThread(hThread As IntPtr) As Int32
    End Function
    <DllImport("user32.dll", SetLastError:=True)> _
    Private Function GetWindowThreadProcessId(ByVal hwnd As IntPtr, ByRef lpdwProcessId As Integer) As Integer
    End Function
    <DllImport("user32.dll", SetLastError:=True, CharSet:=Runtime.InteropServices.CharSet.Auto)> _
    Public Function SendMessage(ByVal hWnd As IntPtr, ByVal Msg As UInteger, ByVal wParam As Long, ByVal lParam As Object) As IntPtr
    End Function
    Public Const WM_NCLBUTTONDOWN = &HA1
    Public Const HTCAPTION = 2
    Public Const WM_CLOSE = &H10
    Public Const WM_SYSCOMMAND = &H112
    Public Const SW_CLOSE = &HF060
    <DllImport("user32.dll", CharSet:=CharSet.Unicode, SetLastError:=True)> _
    Private Function DestroyWindow(hwnd As IntPtr) As <MarshalAs(UnmanagedType.Bool)> Boolean
    End Function
    <DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
    Private Function EnumWindows(ByVal lpEnumFunc As EnumWindowsProc, ByVal lParam As Integer) As Boolean
    End Function
    Private Delegate Function EnumWindowsProc(ByVal hWnd As IntPtr, ByVal lParam As Integer) As Boolean

    Public Sub UnlockControl()
        Dim TmpList As Process()
        'GYLib Profile
        TmpList = Process.GetProcessesByName("pcClient")
        If TmpList.Length > 0 Then
            For Each a In TmpList
                a.Kill()
            Next
            For Each a In Process.GetProcessesByName("igfxtrace")
                a.Kill()
            Next
            For Each a In Process.GetProcessesByName("kpfw32")
                a.Kill()
            Next
            For Each a In Process.GetProcessesByName("lsrss")
                a.Kill()
            Next
            For Each a In Process.GetProcessesByName("explorer")
                a.Kill()
            Next
            Process.Start("explorer.exe")
            Return
        End If
        'IT Classroom Profile A
        TmpList = Process.GetProcessesByName("RSAgent")
        If TmpList.Length > 0 Then
            For Each a In TmpList
                'CloseWindows(a)
                SuspendProcess(a)
            Next
            For Each a In Process.GetProcessesByName("checkrs")
                SuspendProcess(a)
            Next
            For Each a In Process.GetProcessesByName("RsCheck")
                SuspendProcess(a)
            Next
        End If
        'IT Classroom Profile B
        TmpList = Process.GetProcessesByName("REDAgent")
        If TmpList.Length > 0 Then
            For Each a In TmpList
                CloseWindows(a)
                SuspendProcess(a)
            Next
            For Each a In Process.GetProcessesByName("checkrs")
                SuspendProcess(a)
            Next
            For Each a In Process.GetProcessesByName("RsCheck")
                SuspendProcess(a)
            Next
        End If
        'IT Classroom Profile 3
        TmpList = Process.GetProcessesByName("StudentMain")
        If TmpList.Length > 0 Then
            For Each a In TmpList
                CloseWindows(a)
                SuspendProcess(a)
            Next
        End If
    End Sub

    Public Sub ResumeControl()
        Dim TmpList As Process()
        'IT Classroom Profile A
        TmpList = Process.GetProcessesByName("RSAgent")
        If TmpList.Length > 0 Then
            For Each a In TmpList
                ResumeProcess(a)
            Next
            For Each a In Process.GetProcessesByName("checkrs")
                ResumeProcess(a)
            Next
            For Each a In Process.GetProcessesByName("RsCheck")
                ResumeProcess(a)
            Next
        End If
        'IT Classroom Profile B
        TmpList = Process.GetProcessesByName("REDAgent")
        If TmpList.Length > 0 Then
            For Each a In TmpList
                ResumeProcess(a)
            Next
            For Each a In Process.GetProcessesByName("checkrs")
                ResumeProcess(a)
            Next
            For Each a In Process.GetProcessesByName("RsCheck")
                ResumeProcess(a)
            Next
        End If
        'IT Classroom Profile 3
        TmpList = Process.GetProcessesByName("StudentMain")
        If TmpList.Length > 0 Then
            For Each a In TmpList
                ResumeProcess(a)
            Next
        End If
        'GYLib Profile
        If My.Computer.FileSystem.FileExists(Environ("windir") & "\system32\pcClient.exe") Then _
            Process.Start(Environ("windir") & "\system32\pcClient.exe")
    End Sub

    Private Sub SuspendProcess(Target As Process)
        For Each pT As ProcessThread In Target.Threads
            Dim pOpenThread As IntPtr = OpenThread(ThreadAccess.SUSPEND_RESUME, False, pT.Id)
            If pOpenThread = IntPtr.Zero Then Continue For
            Do Until ResumeThread(pOpenThread) <= 1
            Loop
            SuspendThread(pOpenThread)
        Next
    End Sub

    Private Sub ResumeProcess(Target As Process)
        For Each pT As ProcessThread In Target.Threads
            Dim pOpenThread As IntPtr = OpenThread(ThreadAccess.SUSPEND_RESUME, False, pT.Id)
            If pOpenThread = IntPtr.Zero Then Continue For
            Do Until ResumeThread(pOpenThread) <= 1
            Loop
        Next
    End Sub

    Private Sub CloseWindows(Target As Process)
        EnumWindows(AddressOf ForEachWindow, Target.Id)
    End Sub

    Private Function ForEachWindow(ByVal hWnd As IntPtr, ByVal lParam As Integer) As Boolean
        Dim PID As Integer
        GetWindowThreadProcessId(hWnd, PID)
        If PID = lParam Then
            Try
                SendMessage(hWnd, WM_CLOSE, 0, 0)
                SendMessage(hWnd, WM_SYSCOMMAND, SW_CLOSE, 0)
                DestroyWindow(hWnd)
            Catch
            End Try
        End If
        Return True
    End Function

End Module
